package com.hailin.pigserver.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration
@MapperScan(basePackages = PigServerDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "pigServerSqlSessionFactory")
public class PigServerDataSourceConfig {

    private static final Logger logger = LoggerFactory.getLogger(PigServerDataSourceConfig.class);

    public static final String PACKAGE = "com.hailin.pigserver.dao";

    public static final String MODEL = "com.hailin.pigapi.model";

    //第一步中配置文件中的数据库配置信息
    @Value("${pig.datasource.driver-class-name}")
    private String driver;
    @Value("${pig.datasource.url}")
    private String dbUrl;
    @Value("${pig.datasource.username}")
    private String dbUser;
    @Value("${pig.datasource.password}")
    private String dbPassword;

    @Value("${pig.datasource.initialSize}")
    private Integer initialSize;
    @Value("${pig.datasource.minIdle}")
    private Integer minIdle;
    @Value("${pig.datasource.maxActive}")
    private Integer maxActive;
    @Value("${pig.datasource.maxWait}")
    private Long maxWait;

    @Value("${pig.datasource.timeBetweenEvictionRunsMillis}")
    private Long timeBetweenEvictionRunsMillis;
    @Value("${pig.datasource.minEvictableIdleTimeMillis}")
    private Long minEvictableIdleTimeMillis;
    @Value("${pig.datasource.validationQuery}")
    private String validationQuery;
    @Value("${pig.datasource.testWhileIdle}")
    private Boolean testWhileIdle;
    @Value("${pig.datasource.testOnBorrow}")
    private Boolean testOnBorrow;
    @Value("${pig.datasource.testOnReturn}")
    private Boolean testOnReturn;

    @Value("${pig.datasource.poolPreparedStatements}")
    private Boolean poolPreparedStatements;
    @Value("${pig.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private Integer maxPoolPreparedStatementPerConnectionSize;
    @Value("${pig.datasource.connectionProperties}")
    private java.util.Properties connectionProperties;

    @Bean(name = "pigServerDataSource")
    public DruidDataSource getDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        //基本信息
        druidDataSource.setDriverClassName(driver);
        druidDataSource.setUrl(dbUrl);
        druidDataSource.setUsername(dbUser);
        druidDataSource.setPassword(dbPassword);
        //配置初始化大小、最小、最大
        druidDataSource.setInitialSize(initialSize);
        druidDataSource.setMinIdle(minIdle);
        druidDataSource.setMaxActive(maxActive);
        //配置获取连接等待超时的时间
        druidDataSource.setMaxWait(maxWait);
        //配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
        druidDataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        //配置一个连接在池中最小生存的时间，单位是毫秒
        druidDataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        druidDataSource.setValidationQuery(validationQuery);
        druidDataSource.setTestWhileIdle(testWhileIdle);
        druidDataSource.setTestOnBorrow(testOnBorrow);
        druidDataSource.setTestOnReturn(testOnReturn);
        //打开PSCache，并且指定每个连接上PSCache的大小mysql可以配置为false
        druidDataSource.setPoolPreparedStatements(poolPreparedStatements);
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        //通过connectProperties属性来打开mergeSql功能；慢SQL记录
        druidDataSource.setConnectProperties(connectionProperties);
        logger.info("====================     获取数据源成功       =================");
        return druidDataSource;
    }

    @Bean(name = "pigServerDataSourceTransactionManager")
    public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("pigServerDataSource") DruidDataSource druidDataSource){
        return new DataSourceTransactionManager(druidDataSource);
    }

    @Bean(name = "pigServerSqlSessionFactory")
    public SqlSessionFactory getSqlSessionFactory(@Qualifier("pigServerDataSource") DruidDataSource druidDataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(druidDataSource);
        sqlSessionFactoryBean.setTypeAliasesPackage(PigServerDataSourceConfig.MODEL);
        //添加XML目录
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
        } catch (Exception e) {
            logger.error("===========      获取SqlSessionFactory出错      ==========",e);
        }
        return sqlSessionFactoryBean.getObject();
    }
}
